import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.util.Iterator;
import java.util.Random;


public class SnakeEngine{

	public static final int UP =1;
	public static final int RIGHT =2;
	public static final int DOWN= 3;
	public static final int LEFT=4;
	
	
	private Rectangle frame;
	private Snake snake;
	private Point apple;
	private boolean started;
	private boolean paused;
	private boolean loose;
	private int movement;
	private int lastMovement;
	
	public SnakeEngine(Dimension d){
		frame=new Rectangle(d);			
		snake = new Snake(rndPoint());
		regenApple();
		started = false;
		paused = false;
		loose = false;
	}
	
	private Point rndPoint() {
		Random rnd = new Random();
		int x = rnd.nextInt(frame.width);
		int y = rnd.nextInt(frame.height);
		return new Point(x,y);
	}
	
	private void regenApple(){
		Point newApple;
		do {
			newApple = rndPoint();
		} while (snake.isOver(newApple));
		apple = newApple;
	}
	
	
	public void restart(){
		snake = new Snake(rndPoint());
		regenApple();
		started = false;
		paused = false;
		loose = false;
		movement=0;
		lastMovement=0;
		GameWindow.refreshPoint();
		GameWindow.startTimer();
	}
	public void step(){
		if(!loose && !paused){
			move();
		}
	}
	public void setMovement(int nextMov){
		
		started = true;
		if(!loose && !paused ){
			if(nextMov==UP && lastMovement!=DOWN){
				movement = UP;
			}else if(nextMov==RIGHT && lastMovement!=LEFT){
				movement = RIGHT;
			}else if(nextMov==DOWN && lastMovement!=UP){
				movement = DOWN;
			}else if(nextMov==LEFT && lastMovement!=RIGHT){
				movement = LEFT;
			}
		}
	}

	
	private void move(){
			Point snakeHead = snake.getHeadLocation();				
			
			if(movement==UP){
				snakeHead.translate(0, -1);
				if(frame.contains(snakeHead)){
					snake.turnUp();
				}else{
					snakeHead.move(snakeHead.x, frame.height-1);
					snake.jump(snakeHead);
				}
				
			}else if(movement==RIGHT){
				snakeHead.translate(1, 0);
				if(frame.contains(snakeHead)){
					snake.turnRight();
				}else{
					snakeHead.move(0,snakeHead.y);
					snake.jump(snakeHead);
				}
				
			}else if(movement==DOWN){
				snakeHead.translate(0, 1);
				if(frame.contains(snakeHead)){
					snake.turnDown();
				}else{
					snakeHead.move(snakeHead.x,0);
					snake.jump(snakeHead);
				}
				
			}else if(movement==LEFT){
				snakeHead.translate(-1, 0);
				if(frame.contains(snakeHead)){
					snake.turnLeft();
				}else{
					snakeHead.move(frame.width-1,snakeHead.y);
					snake.jump(snakeHead);
				}
			}
			
			lastMovement = movement;
				
			if(snake.autoBeaten()){
				loose=true;
				GameWindow.refreshGameDisplay();
				GameWindow.stopTimer();
			}else if(snake.isOver(apple)){
				snake.eat(1);
				regenApple();
				GameWindow.refreshPoint();
			}
		
	}
	
	//metodi per restituire i punti da stampare
	public Iterator<Point> getSnake(){
		return snake.iterator();
	}
	public Point getApple(){
		return (Point) apple.clone();
	}
	
	//metodi sullo stato
	public boolean isStarted(){
		return started;
	}
	public void start(){
		started = true;
		paused = false;
		GameWindow.startTimer();
	}
	public boolean isPaused(){
		return paused;
	}
	public void pause(){
		if(started){
		paused = true;
		GameWindow.refreshGameDisplay();
		GameWindow.stopTimer();
		}
	}
	public boolean loosed(){
		return loose;
	}
	public int getSnakeLong(){
		return snake.size();
	}
	
}
